package _2_函数_运算._6_lambda;

import _0_object_oriented.Bean;
import _0_object_oriented.User;
import com.google.common.base.CaseFormat;
import com.google.common.collect.Lists;
import java.util.function.Predicate;
import org.junit.Test;

import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * Created by bpzj on 2018/4/20.
 */
public class _6_LambdaTest {

  public static byte easeMobId = 1;

  // Predicate 的用法, Stream的 filter 方法
//  @Test
  public void filterWithPredicate() {
    //  使用默认的 Stream 类的 filter 方法
    List<String> old = Lists.newArrayList("1","2");
    List<String> afterFilter = old.stream().filter(i -> i.equals("1")).collect(Collectors.toList());
    System.out.println(afterFilter);
    System.out.println(old);

    //  自定义 Predicate
    List<User> userList = Lists.newArrayList(new User("name", 10), new User("haha", 16), new User("lele", 18));
    List<User> 成年人 = UserWithLambda.filterApple(userList, user -> user.getAge() >= 18);
    Predicate<User> name = user -> user.getName().equals("name");
    List<User> 指定name = UserWithLambda.filterApple(userList, name);

    _6_LambdaTest test = new _6_LambdaTest();
    CustomDefine<User> ingredient = this::mapRowToIngredient;

    // todo 更改成自定义的
  }

  private User mapRowToIngredient(Map<String,String> map, int rowNum) {
    return new User(map.get("name"), Integer.parseInt(map.get("age")));
  }

  /**
   Predicate<T>接口：默认调用test方法，返回boolean值，传递的参数只有一个。
   在需要调用Lambeda表达式返回boolean的时候使用。
   */


  @Test
  public void iterableTest() {

    //    ->  符号
    //  (x, y) -> x + y ;        多个参数
    //  () -> { code } ;

    List<String> languages = Arrays.asList("java", "scala", "python");
    languages.forEach(x -> System.out.println(x));
    // 用 method reference 更简洁，推荐使用:
    languages.forEach(System.out::println);

    // Stream 类，内部迭代
    //  1. get Stream
    //          1.1  Collection 接口的 所有实现类 都有 stream() 方法
    //          1.2  Stream.of()
    //  2. 惰性求值 Stream 继续转为 Stream
    //          2.1  map, filter, flatMap, max, min
    //  3. 及早求值 得到结果
    //          3.1  collect

    // String[] 转为 int[]
    String arrayStr = "1,2,3";
    int[] integers = Arrays.stream(arrayStr.split(",")).mapToInt(Integer::parseInt).toArray();
    int[] ints = Pattern.compile(",").splitAsStream(arrayStr).mapToInt(Integer::parseInt).toArray();
    Integer max = Arrays.stream(integers).max().orElseThrow(IllegalArgumentException::new);
    System.out.println(max);
  }

  /**
   * List 每个元素 进行 一定的转化
   */

  //      1. List<String> 每个元素 _下划线变量名转为 驼峰命名
  @Test
  public void underScoreCaseToCamelcase() {
    List<String> underScore = Lists.newArrayList("liu_ya_min_is", "my_favorite");
    List<String> camelCase = underScore
        .stream()
        .map(item -> CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, item))
        .collect(Collectors.toList());
    System.out.println(camelCase);
  }

  /**
   * 各种对象 和 Map 直接转换
   */
  //      1. 从 java bean 中取两个属性，一个作 key，一个作 value，转为 map
  @Test
  public void beanPropertyToMap() {
    List<Bean> beanList = Lists.newArrayList(new Bean("ym", "best"), new Bean("wy", "white"));

    // list组装完成 开始转换 不推荐
    Map<String, Object> objectMap = new HashMap<>();
    beanList.forEach(item -> objectMap.put(item.getKey(), item.getValue()));
    System.out.println(objectMap);

    // 另一种方法，推荐
    Map<String, Object> map = beanList.stream()
        .collect(Collectors.toMap(Bean::getKey, Bean::getValue));

    System.out.println(map);

  }


  /**
   * Map<String, Object> 转为  Map<String, String>
   */
  @Test
  public void mapTrans() {
    // this branch is crested from bpzj branch
  }

}
